﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Collections;
using System.Xml;
using System.Data;

using Utilities;

using Google.GData.Client; 

namespace EvriConnector
{
    public class UrlBuilder
    {
        string m_appId = "appId=evri.com-restdoc";
        string m_apiRoot = "http://api.evri.com";
        string m_entityRelative = "/v1/entities?query=";
        public enum ResponseType { xml, json};
        Dictionary<ResponseType, string> m_responseType;

        public UrlBuilder()
        {
            m_responseType = new Dictionary<ResponseType, string>();

            m_responseType.Add(ResponseType.xml,    ".xml");
            m_responseType.Add(ResponseType.json, ".json");
        }

        public Uri CreateEntityUrl(string relativePart)
        {
            return new Uri(m_apiRoot + relativePart);
        }

        public Uri CreateLookUpUrl(string entity)
        {
            string resultUrl = m_apiRoot + m_entityRelative + entity + "&" + m_appId;
            
            return new Uri(resultUrl);
        }

    }
    public class ServiceHost
    {
        //make find entity request,
        //return the list of parsed entities
        public Entity[] EntityLookUp(string entity)
        {
            string [] search_entities = entity.Split(new Char[]{'|'});
            
            Entity[] result = null;
            Hashtable table = new Hashtable(); 

            foreach (string search_entry in search_entities)
            {
                Uri entityUri = new UrlBuilder().CreateLookUpUrl(search_entry);

                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(entityUri);
                // in other case the "json" will be returned
                request.Accept = "application/xml";
                request.Proxy = Google.GData.Client.Utilities.CommonOperations.GetProxy();
       
                HttpWebResponse response = null;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();

                    StreamReader reader = new StreamReader(response.GetResponseStream());
                    XmlDocument xd = new XmlDocument();
                    xd.Load(reader);
                    XmlNodeList entityList = xd.GetElementsByTagName("entityList");

                    Entity[] res = new EntityParser().Process(entityList);
                    for (int i = 0; i < res.Length; i++)
                    {
                        try
                        {
                            table.Add(res[i].href, res[i]);
                        }
                        catch (Exception e)
                        {

                        }
                    }
                    /*
                    if (result == null)
                    {
                        result = new Entity[res.Length];
                        res.CopyTo(result, 0);
                    }
                    else
                    {
                        Array.Resize(ref result, result.Length + res.Length);
                        res.CopyTo(result, result.Length - res.Length); 
                    }
                    */

                }
                catch (Exception e)
                {

                }
                finally
                {
                    response.Close();
                }

            }

            result = new Entity[table.Count];
            table.Values.CopyTo(result, 0);
            
            return result;
        }

        //return the entity that matches the criteria the most
        //currently - the top score is the sign
        public Entity GetTopEntity(Entity[] entities)
        {
            System.Array.Sort(entities);
            return entities[0];
        }

        private StreamReader MakeEntityRequest(Entity ent)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new UrlBuilder().CreateEntityUrl(ent.href));

            HttpWebResponse response = null;
            StreamReader reader = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();

                reader = new StreamReader(response.GetResponseStream());
            }
            finally
            {
                response.Close();
            }

            return reader;
        }

        private static string RSS_Header = "<rss version=\"2.0\">" + 
                                    "<channel>" + 
                                    "<title>Uprise Apps Search Results</title>" +
                                    "<link>http://www.upriseapps.com</link>" + 
                                    "<description>Uprise Apps - Web Content Aggregation</description>" + 
                                    "<image>" + 
                                    "<url>http://www.upriseapps.com/images/logo_upriseapps_color.jpg</url>" + 
                                    "<link>http://www.upriseapps.com</link>" +  
                                    "<title>Uprise Apps</title>" +
                                    "</image>";

        private static string RSS_Footer = "</channel></rss>";

        private string MakeEntityRequestRSS(Entity ent)
        {
            string entry_details;
            string rss_item = "";
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(new UrlBuilder().CreateEntityUrl(ent.href));
            request.Proxy = Google.GData.Client.Utilities.CommonOperations.GetProxy();
       
            HttpWebResponse response = null;
            StreamReader reader = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();

                reader = new StreamReader(response.GetResponseStream());
                entry_details = reader.ReadToEnd();

                XmlDocument xml = new XmlDocument();
                xml.LoadXml(entry_details);
                //xml.GetElementsByTagName(
                XmlNodeList prop_list = xml.GetElementsByTagName("property");
                if (prop_list != null)
                {


                    rss_item = "<item>";
                    rss_item += "<title>" + System.Security.SecurityElement.Escape(ent.name) + "</title>";
                    rss_item += "<category>" + System.Security.SecurityElement.Escape(ent.type) + "</category>";

                    foreach (XmlNode prop_node in prop_list)
                    {

                        if (prop_node.ChildNodes[0].InnerText == "source_url")
                            rss_item += "<link>" + System.Security.SecurityElement.Escape(prop_node.ChildNodes[1].InnerText) + "</link>";
                        if (prop_node.ChildNodes[0].InnerText == "wikipedia_paragraph")
                            rss_item += "<description>" + System.Security.SecurityElement.Escape(prop_node.ChildNodes[1].InnerText) + "</description>";
                       
                    }
                    rss_item += "</item>";
                }

                if (ent.type == "ORGANIZATION")
                {
                    if (prop_list != null)
                    {

                        foreach (XmlNode prop_node in prop_list)
                        {
                            if (prop_node.ChildNodes[0].InnerText == "key_person")
                            {
                                string[] values = System.Security.SecurityElement.Escape(prop_node.ChildNodes[1].InnerText).Split(',');
                                string name = values[0];
                                string description = "Coming Soon";
                                if (values.Length > 1) description = values[1]; 
                                rss_item += "<item>";
                                rss_item += "<title>" + values[0] + "</title>";
                                rss_item += "<category>" + System.Security.SecurityElement.Escape("PERSON") + "</category>";
                                rss_item += "<link>" + System.Security.SecurityElement.Escape("http://www.linkedin.com") + "</link>";
                                rss_item += "<description>" + description + "</description>";
                                rss_item += "</item>";
                            }
                        }
                    }
                }


               
            }
            catch (Exception ex)
            {

            }
            finally
            {
                if(response!=null)
                    response.Close();
            }

            return rss_item;
        }


        public string ProcessRequestToRSS(string content, ContentFormat requiredFormat)
        {

            Entity[] result = EntityLookUp(content);
            if (result.Length == 0)
                return RSS_Header + RSS_Footer;

            string RSS_Content = ""; 
            /*
             * Entity topEntity = GetTopEntity(result);

            StreamReader topEntityResponse = MakeEntityRequest(topEntity);

            //apply the xslt conversion
            FormatConvertor convert = new FormatConvertor(requiredFormat);
            return convert.DoFormatting(topEntityResponse);
            */
            foreach(Entity entry in result)
            {
                RSS_Content += MakeEntityRequestRSS(entry); 
            }

            return RSS_Header + RSS_Content + RSS_Footer;
        }

        public Stream ProcessRequest(string content, ContentFormat requiredFormat)
        {
          Entity[] result = EntityLookUp(content);
          if (result.Length == 0)
              return null;

          Entity topEntity = GetTopEntity(result);
          
          StreamReader topEntityResponse = MakeEntityRequest(topEntity);

          //apply the xslt conversion
          FormatConvertor convert = new FormatConvertor(requiredFormat);
          return convert.DoFormatting(topEntityResponse);
        }
    }
}
